package com.jingbit.ai.helper;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;

import com.jingbit.ai.base.BaseApp;

import net.ossrs.yasea.R;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class FileHelper {
	private static final String TAG = "FileHelper";
	public static final int SIZETYPE_B = 1;// 获取文件大小单位为B的double值
	public static final int SIZETYPE_KB = 2;// 获取文件大小单位为KB的double值
	public static final int SIZETYPE_MB = 3;// 获取文件大小单位为MB的double值
	public static final int SIZETYPE_GB = 4;// 获取文件大小单位为GB的double值

	public static final String IMAGE_SMALL_CACHE_DIR = "images_small_cache";// 小图所放路径的文件夹名
	public static final String IMAGE_CACHE_DIR = "images_cache";// 默认图所放路径的文件夹名
	public static final String AUDIO_CACHE_DIR = "audios_cache";// 默认语音所放路径的文件夹名
	public static final String VIDEO_CACHE_DIR = "videos_cache";// 默认视频所放路径的文件夹名
	
	public static final int DO_CANCEL_RESULT = 5; // 取消
	public static final int DO_CAMERA_RESULT = 6;// 拍照
	public static final int DO_GALLERY_RESULT = 7; // 相册
	public static final int DO_CROP_RESULT = 8;// 裁剪结果
	private static final String LINE_SEP = System.getProperty("line.separator");
	/**
	 * 
	 * Object对象转byte数组
	 * 
	 * @param obj
	 * @return byte[]
	 */
	public static byte[] obj2Bytes(Object obj) {
		byte[] bytes = null;
		ByteArrayOutputStream bo = null;
		ObjectOutputStream oo = null;
		try {
			bo = new ByteArrayOutputStream();
			oo = new ObjectOutputStream(bo);
			oo.writeObject(obj);
			bytes = bo.toByteArray();
		} catch (Exception e) {
			Logger.log(TAG, "obj2Byte err", e);
		} finally {
			closeOutStreamQuietly(bo);
			closeOutStreamQuietly(oo);
		}
		return bytes;
	}

	/**
	 * 
	 * byte数组转对象
	 * 
	 * @param bytes
	 * @return Object
	 */

	public static Object bytes2Obj(byte[] bytes) {
		Object obj = null;
		ByteArrayInputStream bi = null;
		ObjectInputStream oi = null;
		try {
			bi = new ByteArrayInputStream(bytes);
			oi = new ObjectInputStream(bi);
			obj = oi.readObject();
		} catch (Exception e) {
			Logger.log(TAG, "bytes2Obj err", e);
		} finally {
			closeInStreamQuietly(bi);
			closeInStreamQuietly(oi);
		}
		return obj;
	}

	/**
	 * 
	 * 输入流关闭
	 * 
	 * @param inStream
	 *            void
	 */

	public static void closeInStreamQuietly(InputStream inStream) {
		if (inStream != null) {
			try {
				inStream.close();
			} catch (IOException e) {
				Logger.log(TAG, "closeInStreamQuietly err", e);
			} finally {
				inStream = null;
			}
		}

	}

	/**
	 * 
	 * 输出流关闭
	 * 
	 * @param outStream
	 *            void
	 */

	public static void closeOutStreamQuietly(OutputStream outStream) {
		if (outStream != null) {
			try {
				outStream.flush();
				outStream.close();
			} catch (IOException e) {
				Logger.log(TAG, "closeOutStreamQuietly err", e);
			} finally {
				outStream = null;
			}
		}
	}

	/**
	 * 获得指定文件的byte数组
	 */
	public static byte[] file2Bytes(File file) {
		if (!file.exists()) {
			return null;
		}
		FileInputStream fiStream = null;
		ByteArrayOutputStream boStream = null;
		try {
			fiStream = new FileInputStream(file);
			boStream = new ByteArrayOutputStream();
			byte[] bytes = new byte[1024 * 10];
			int len;
			while ((len = fiStream.read(bytes)) != -1) {
				boStream.write(bytes, 0, len);
			}
			return boStream.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (fiStream != null) {
					fiStream.close();
				}
				if (boStream != null) {
					boStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 根据byte数组，生成文件
	 * 
	 * @param fileBytes
	 */
	public static File bytes2File(byte[] fileBytes, String filePath) {
		File byteFile = new File(filePath);
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(byteFile);
			bos = new BufferedOutputStream(fos);
			bos.write(fileBytes);
			return byteFile;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			Logger.log(TAG, "bytes2File finally");
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
		return null;
	}
	
	private static String getRootPath(){
		return Environment.getExternalStorageDirectory().getAbsolutePath();
	}

	/**
	 * 获取sdcard程序缓存路径
	 * 
	 * @return
	 */
	public static String getDiskPath(){
		File file = new File(getRootPath() + File.separator
				+ BaseApp.application.getString(R.string.app_name));
		if (!file.exists()) {
			file.mkdirs();
		}
		return file.getAbsolutePath();
	}

	/**
	 * 获取内存中程序缓存路径
	 * 
	 * @return
	 */
	public static String getCachePath() {
		File file = new File(BaseApp.application.getCacheDir().getAbsolutePath()
				+ File.separator + "cache");
		if (!file.exists()) {
			file.mkdirs();
		}
		return file.getAbsolutePath();
	}

	/**
	 * 获取sdcard中程序缓存路径
	 * 
	 * @return
	 */
	public static String getDiskCachePath(String cacheName) {
		File file = new File(getDiskPath() + File.separator + "cache"
				+ File.separator + cacheName);
		if (!file.exists()) {
			file.mkdirs();
		}
		return file.getAbsolutePath();
	}

	/**
	 * 内存中程序数据存储路径
	 * 
	 * @param fileName
	 * @return
	 */
	public static File getDataFile(String fileName) {
		File file = new File("/data"
				+ Environment.getDataDirectory().getAbsolutePath()
				+ File.separator
				+ BaseApp.getApp().getPackageName()
				+ File.separator + fileName);
		return file;
	}

	/**
	 * 自己拼接后缀名
	 * 
	 * @return
	 */
	public static String getFileNameByFmt(String format) {
		String fileName = "TMP_" + DateHelper.getDateFormat("yyyyMMddHHmmss")
				+ format;
		return fileName;
	}

	/**
	 * 创建文件
	 * 
	 * @param filePath
	 * @return
	 */
	public static File createNewFile(String filePath) {
		File file = new File(filePath);
		if (!file.exists()) {
			if (file.isDirectory()) {
				file.mkdirs();
			} else {
				try {
					file.createNewFile();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return file;
	}

	/**
	 * 给定的文件路径和文件名 创建文件
	 * 
	 * @param filePath
	 *            给定的路径
	 * @param fileName
	 *            文件名
	 * @return
	 */
	public static File createNewFile(String filePath, String fileName) {
		File fileDir = new File(filePath);
		if (!fileDir.exists()) {
			fileDir.mkdir();
		}
		File file = new File(fileDir.getAbsolutePath() + "/" + fileName);
		if (file.exists()) {
			return createNewFile(filePath, fileName);
		} else {
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return file;
		}
	}

	/**
	 * 从指定文件中读取对象
	 * 
	 * @param file
	 * @return object
	 */
	public static Object readObj(File file) {
		try {
			ObjectInputStream read = new ObjectInputStream(
					new BufferedInputStream(new FileInputStream(file)));
			Object obj = read.readObject();
			read.close();
			return obj;
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * 通过uri获取文件路径
	 * 
	 * @param context
	 * @param fileUri
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static File getFileByUri(Activity context, Uri fileUri) {
		String[] proj = { MediaStore.Images.Media.DATA };
		Cursor cursor = context.managedQuery(fileUri, proj, null, null, null);
		if (cursor != null) {
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			String img_path = cursor.getString(column_index);
			// 4.0以上的版本会自动关闭 (4.0--14;; 4.0.3--15)
			if (Integer.parseInt(Build.VERSION.SDK) < 14) {
				cursor.close();
			}
			File file = new File(img_path);
			return file;
		} else
			return null;
	}

	/**
	 * 通过文件路径获取Uri
	 * 
	 * @param filePath
	 * @return
	 */
	public static Uri getUriByFile(String filePath) {
		File file = new File(filePath);
		if (!file.exists()) {
			return null;
		}
		return Uri.fromFile(file);
	}

	
	public static String getFormat(String fileName) {
		int index = fileName.lastIndexOf(".");
		if (index != -1) {
			String format = fileName.substring(index, fileName.length());
			return format;
		}
		return ".png";
	}

	/**
	 * 获取文件路径
	 * 
	 * @param imgLink
	 * @return
	 */
	public static File getFileByLink(String imgLink) {
		if (!StringHelper.hasValue(imgLink)) {
			return null;
		}
		String format=getFormat(imgLink);
		File file = new File(getDiskCachePath(IMAGE_CACHE_DIR) 
				+ File.separator+ imgLink.hashCode() + format);
		return file;
	}
	
	
	/**
	 * read file
	 * 
	 * @param filePath
	 * @param charsetName
	 * @return if file not exist, return null, else return content of file
	 * @throws RuntimeException
	 *             if an error occurs while operator BufferedReader
	 */
	public static StringBuilder readFile(String filePath, String charsetName) {
		File file = new File(filePath);
		StringBuilder fileContent = new StringBuilder("");
		if (file == null || !file.isFile()) {
			return null;
		}

		BufferedReader reader = null;
		try {
			InputStreamReader is = new InputStreamReader(new FileInputStream(
					file), charsetName);
			reader = new BufferedReader(is);
			String line = null;
			while ((line = reader.readLine()) != null) {
				if (!fileContent.toString().equals("")) {
					fileContent.append("\r\n");
				}
				fileContent.append(line);
			}
			reader.close();
			return fileContent;
		} catch (IOException e) {
			throw new RuntimeException("IOException occurred. ", e);
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					throw new RuntimeException("IOException occurred. ", e);
				}
			}
		}
	}

	/**
	 * write file
	 * 
	 * @param filePath
	 * @param content
	 * @param append
	 *            is append, if true, write to the end of file, else clear
	 *            content of file and write into it
	 * @return return false if content is empty, true otherwise
	 * @throws RuntimeException
	 *             if an error occurs while operator FileWriter
	 */
	public static boolean writeFile(String filePath, String content,
			boolean append) {
		if (!StringHelper.hasValue(content)) {
			return false;
		}

		FileWriter fileWriter = null;
		try {
			fileWriter = new FileWriter(filePath, append);
			fileWriter.write(content);
			fileWriter.close();
			return true;
		} catch (IOException e) {
			throw new RuntimeException("IOException occurred. ", e);
		} finally {
			if (fileWriter != null) {
				try {
					fileWriter.close();
				} catch (IOException e) {
					throw new RuntimeException("IOException occurred. ", e);
				}
			}
		}
	}

	/**
	 * write file
	 * 
	 * @param filePath
	 * @param contentList
	 * @param append
	 */
	public static boolean writeFile(String filePath, List<String> contentList,
			boolean append) {

		FileWriter fileWriter = null;
		try {
			fileWriter = new FileWriter(filePath, append);
			int i = 0;
			for (String line : contentList) {
				if (i++ > 0) {
					fileWriter.write("\r\n");
				}
				fileWriter.write(line);
			}
			fileWriter.close();
			return true;
		} catch (IOException e) {
			throw new RuntimeException("IOException occurred. ", e);
		} finally {
			if (fileWriter != null) {
				try {
					fileWriter.close();
				} catch (IOException e) {
					throw new RuntimeException("IOException occurred. ", e);
				}
			}
		}
	}

	/**
	 * write file, the string will be written to the begin of the file
	 * 
	 * @param filePath
	 * @param content
	 * @return
	 */
	public static boolean writeFile(String filePath, String content) {
		return writeFile(filePath, content, false);
	}

	/**
	 * write file, the string list will be written to the begin of the file
	 * 
	 * @param filePath
	 * @param contentList
	 * @return
	 */
	public static boolean writeFile(String filePath, List<String> contentList) {
		return writeFile(filePath, contentList, false);
	}

	/**
	 * write file, the bytes will be written to the begin of the file
	 * 
	 * @param filePath
	 * @param stream
	 * @return
	 */
	public static boolean writeFile(String filePath, InputStream stream) {
		return writeFile(filePath, stream, false);
	}

	/**
	 * write file
	 * @param stream
	 *            the input stream
	 * @param append
	 *            if <code>true</code>, then bytes will be written to the end of
	 *            the file rather than the beginning
	 * @return return true
	 * @throws RuntimeException
	 *             if an error occurs while operator FileOutputStream
	 */
	public static boolean writeFile(String filePath, InputStream stream,
			boolean append) {
		return writeFile(filePath != null ? new File(filePath) : null, stream,
				append);
	}

	/**
	 * write file, the bytes will be written to the begin of the file
	 * 
	 * @param file
	 * @param stream
	 * @return
	 */
	public static boolean writeFile(File file, InputStream stream) {
		return writeFile(file, stream, false);
	}

	/**
	 * write file
	 * 
	 * @param file
	 *            the file to be opened for writing.
	 * @param stream
	 *            the input stream
	 * @param append
	 *            if <code>true</code>, then bytes will be written to the end of
	 *            the file rather than the beginning
	 * @return return true
	 * @throws RuntimeException
	 *             if an error occurs while operator FileOutputStream
	 */
	public static boolean writeFile(File file, InputStream stream,
			boolean append) {
		OutputStream o = null;
		try {
			o = new FileOutputStream(file, append);
			byte data[] = new byte[1024];
			int length = -1;
			while ((length = stream.read(data)) != -1) {
				o.write(data, 0, length);
			}
			o.flush();
			return true;
		} catch (FileNotFoundException e) {
			throw new RuntimeException("FileNotFoundException occurred. ", e);
		} catch (IOException e) {
			throw new RuntimeException("IOException occurred. ", e);
		} finally {
			if (o != null) {
				try {
					o.close();
					stream.close();
				} catch (IOException e) {
					throw new RuntimeException("IOException occurred. ", e);
				}
			}
		}
	}

	/**
	 * copy file
	 * @param sourceFilePath
	 * @param destFilePath
	 * @return
	 * @throws RuntimeException
	 *             if an error occurs while operator FileOutputStream
	 */
	public static boolean copyFile(String sourceFilePath, String destFilePath) {
		InputStream inputStream = null;
		try {
			inputStream = new FileInputStream(sourceFilePath);
		} catch (FileNotFoundException e) {
			throw new RuntimeException("FileNotFoundException occurred. ", e);
		}
		return writeFile(destFilePath, inputStream);
	}


	/**
	 * delete file or directory
	 * @param path
	 * @return
	 */
	public static boolean deleteFile(String path) {
		if (!StringHelper.hasValue(path)) {
			return true;
		}

		File file = new File(path);
		if (!file.exists()) {
			return true;
		}
		if (file.isFile()) {
			return file.delete();
		}
		if (!file.isDirectory()) {
			return false;
		}
		for (File f : file.listFiles()) {
			if (f.isFile()) {
				f.delete();
			} else if (f.isDirectory()) {
				deleteFile(f.getAbsolutePath());
			}
		}
		return file.delete();
	}

	/**
	 * 转换文件大小
	 * 
	 * @param fileSize
	 * @return
	 */
	public static String getFileSize(long fileSize) {
		DecimalFormat df = new DecimalFormat("#.00");
		String fileSizeString = "";
		String wrongSize = "0B";
		if (fileSize == 0) {
			return wrongSize;
		}
		if (fileSize < 1024) {
			fileSizeString = df.format((double) fileSize) + "B";
		} else if (fileSize < 1048576) {
			fileSizeString = df.format((double) fileSize / 1024) + "KB";
		} else if (fileSize < 1073741824) {
			fileSizeString = df.format((double) fileSize / 1048576) + "MB";
		} else {
			fileSizeString = df.format((double) fileSize / 1073741824) + "GB";
		}
		return fileSizeString;
	}

	public static boolean isPictureFile(String fileName){
		if (fileName==null) {
			return false;
		}
		if (fileName.endsWith(".jpg")
				||fileName.endsWith(".gif")
				||fileName.endsWith(".bmp")
				||fileName.endsWith(".png")
				||fileName.endsWith(".jpeg")
				) {
			return true;
		}
		return false;
	}

	/**
	 * 根据文件路径获取文件
	 *
	 * @param filePath 文件路径
	 * @return 文件
	 */
	public static File getFileByPath(final String filePath) {
		return isSpace(filePath) ? null : new File(filePath);
	}

	/**
	 * @param context
	 * @param url     后缀 .jpg
	 * @param type    Environment.DIRECTORY_MUSIC
	 *                Environment.DIRECTORY_PICTURE
	 * @return
	 * @throws IOException
	 */
	public static File getDownloadFile(Context context, String type, String url) {
		File storageDir = null;
		if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
				|| !Environment.isExternalStorageRemovable()) {
			storageDir = Environment.getExternalStoragePublicDirectory(type);
		} else {
			storageDir = new File(Environment.getDownloadCacheDirectory(), type);
		}
		//创建image文件
		return new File(storageDir, getFileNameByUrl(url));
	}

	public static String getFileNameByUrl(String url) {
		if (url == null) {
			return "";
		}
		if (url.contains("/")) {
			return url.substring(url.lastIndexOf("/") + 1);
		}
		return url.hashCode() + ".mp4";
	}

	/**
	 * 根据文件目录路径获取子目录名称（不获取二级子目录）
	 *
	 * @param dirPath 文件路径
	 * @return 文件目录名称
	 */
	public static List<String> getFiledirList(String dirPath) {
		if (dirPath == null || !isDir(dirPath)) return null;
		List<String> stringList = new ArrayList<>();
		File f = new File(dirPath);
		File[] files = f.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				if (file.isDirectory()) {
					stringList.add(file.getName());
				}
			}
		}
		return stringList;
	}

	/**
	 * 判断文件是否存在
	 *
	 * @param filePath 文件路径
	 * @return {@code true}: 存在<br>{@code false}: 不存在
	 */
	public static boolean isFileExists(final String filePath) {
		return isFileExists(getFileByPath(filePath));
	}

	/**
	 * 判断文件是否存在
	 *
	 * @param file 文件
	 * @return {@code true}: 存在<br>{@code false}: 不存在
	 */
	public static boolean isFileExists(final File file) {
		return file != null && file.exists();
	}

	/**
	 * 重命名文件
	 *
	 * @param filePath 文件路径
	 * @param newName  新名称
	 * @return {@code true}: 重命名成功<br>{@code false}: 重命名失败
	 */
	public static boolean rename(final String filePath, final String newName) {
		return rename(getFileByPath(filePath), newName);
	}

	/**
	 * 重命名文件
	 *
	 * @param file    文件
	 * @param newName 新名称
	 * @return {@code true}: 重命名成功<br>{@code false}: 重命名失败
	 */
	public static boolean rename(final File file, final String newName) {
		// 文件为空返回false
		if (file == null) return false;
		// 文件不存在返回false
		if (!file.exists()) return false;
		// 新的文件名为空返回false
		if (isSpace(newName)) return false;
		// 如果文件名没有改变返回true
		if (newName.equals(file.getName())) return true;
		File newFile = new File(file.getParent() + File.separator + newName);
		// 如果重命名的文件已存在返回false
		return !newFile.exists()
				&& file.renameTo(newFile);
	}

	/**
	 * 判断是否是目录
	 *
	 * @param dirPath 目录路径
	 * @return {@code true}: 是<br>{@code false}: 否
	 */
	public static boolean isDir(final String dirPath) {
		return isDir(getFileByPath(dirPath));
	}

	/**
	 * 判断是否是目录
	 *
	 * @param file 文件
	 * @return {@code true}: 是<br>{@code false}: 否
	 */
	public static boolean isDir(final File file) {
		return isFileExists(file) && file.isDirectory();
	}

	/**
	 * 判断是否是文件
	 *
	 * @param filePath 文件路径
	 * @return {@code true}: 是<br>{@code false}: 否
	 */
	public static boolean isFile(final String filePath) {
		return isFile(getFileByPath(filePath));
	}

	/**
	 * 判断是否是文件
	 *
	 * @param file 文件
	 * @return {@code true}: 是<br>{@code false}: 否
	 */
	public static boolean isFile(final File file) {
		return isFileExists(file) && file.isFile();
	}

	/**
	 * 判断目录是否存在，不存在则判断是否创建成功
	 *
	 * @param dirPath 目录路径
	 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败
	 */
	public static boolean createOrExistsDir(final String dirPath) {
		return createOrExistsDir(getFileByPath(dirPath));
	}

	/**
	 * 判断目录是否存在，不存在则判断是否创建成功
	 *
	 * @param file 文件
	 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败
	 */
	public static boolean createOrExistsDir(final File file) {
		// 如果存在，是目录则返回true，是文件则返回false，不存在则返回是否创建成功
		return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());
	}

	/**
	 * 判断文件是否存在，不存在则判断是否创建成功
	 *
	 * @param filePath 文件路径
	 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败
	 */
	public static boolean createOrExistsFile(final String filePath) {
		return createOrExistsFile(getFileByPath(filePath));
	}

	/**
	 * 判断文件是否存在，不存在则判断是否创建成功
	 *
	 * @param file 文件
	 * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败
	 */
	public static boolean createOrExistsFile(final File file) {
		if (file == null) return false;
		// 如果存在，是文件则返回true，是目录则返回false
		if (file.exists()) return file.isFile();
		if (!createOrExistsDir(file.getParentFile())) return false;
		try {
			return file.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 判断文件是否存在，存在则在创建之前删除
	 *
	 * @param file 文件
	 * @return {@code true}: 创建成功<br>{@code false}: 创建失败
	 */
	public static boolean createFileByDeleteOldFile(final File file) {
		if (file == null) return false;
		// 文件存在并且删除失败返回false
		if (file.exists() && !file.delete()) return false;
		// 创建目录失败返回false
		if (!createOrExistsDir(file.getParentFile())) return false;
		try {
			return file.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}


	/**
	 * 删除目录
	 *
	 * @param dirPath 目录路径
	 * @return {@code true}: 删除成功<br>{@code false}: 删除失败
	 */
	public static boolean deleteDir(final String dirPath) {
		return deleteDir(getFileByPath(dirPath));
	}


	/**
	 * 删除文件或目录
	 *
	 * @param file
	 * @return
	 */
	public static boolean deleteDirOrFile(File file) {
		if (file == null) return false;
		if (!file.exists()) return false;
		if (file.isFile()) {
			return deleteFile(file);
		} else {
			return deleteDir(file);
		}
	}

	/**
	 * 删除文件或目录
	 *
	 * @param path
	 * @return
	 */
	public static boolean deleteDirOrFile(String path) {
		return deleteDirOrFile(getFileByPath(path));
	}

	/**
	 * 删除目录
	 *
	 * @param dir 目录
	 * @return {@code true}: 删除成功<br>{@code false}: 删除失败
	 */
	public static boolean deleteDir(final File dir) {
		if (dir == null) return false;
		// 目录不存在返回true
		if (!dir.exists()) return true;
		// 不是目录返回false
		if (!dir.isDirectory()) return false;
		// 现在文件存在且是文件夹
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				if (file.isFile()) {
					if (!file.delete()) return false;
				} else if (file.isDirectory()) {
					if (!deleteDir(file)) return false;
				}
			}
		}
		return dir.delete();
	}

	/**
	 * 删除Luban文件集合 以“|” 分割
	 *
	 * @param srcFilePaths
	 */
	public static void deleteFiles(String srcFilePaths) {
		if (TextUtils.isEmpty(srcFilePaths))
			return;
		List<String> list = Arrays.asList(srcFilePaths.split("\\|"));
		for (String path : list) {
			if (path.contains("luban")) {
				deleteFile(path);
			}
		}
	}

	/**
	 * 删除文件
	 *
	 * @param file 文件
	 * @return {@code true}: 删除成功<br>{@code false}: 删除失败
	 */
	public static boolean deleteFile(final File file) {
		return file != null && (!file.exists() || file.isFile() && file.delete());
	}

	/**
	 * 删除目录下的所有文件
	 *
	 * @param dirPath 目录路径
	 * @return {@code true}: 删除成功<br>{@code false}: 删除失败
	 */
	public static boolean deleteFilesInDir(final String dirPath) {
		return deleteFilesInDir(getFileByPath(dirPath));
	}

	/**
	 * 删除目录下的所有文件
	 *
	 * @param dir 目录
	 * @return {@code true}: 删除成功<br>{@code false}: 删除失败
	 */
	public static boolean deleteFilesInDir(final File dir) {
		if (dir == null) return false;
		// 目录不存在返回true
		if (!dir.exists()) return true;
		// 不是目录返回false
		if (!dir.isDirectory()) return false;
		// 现在文件存在且是文件夹
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				if (file.isFile()) {
					if (!file.delete()) return false;
				} else if (file.isDirectory()) {
					if (!deleteDir(file)) return false;
				}
			}
		}
		return true;
	}

	/**
	 * 获取目录下所有文件
	 *
	 * @param dirPath     目录路径
	 * @param isRecursive 是否递归进子目录
	 * @return 文件链表
	 */
	public static List<File> listFilesInDir(final String dirPath, final boolean isRecursive) {
		return listFilesInDir(getFileByPath(dirPath), isRecursive);
	}

	/**
	 * 获取目录下所有文件
	 *
	 * @param dir         目录
	 * @param isRecursive 是否递归进子目录
	 * @return 文件链表
	 */
	public static List<File> listFilesInDir(final File dir, final boolean isRecursive) {
		if (!isDir(dir)) return null;
		if (isRecursive) return listFilesInDir(dir);
		List<File> list = new ArrayList<>();
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			Collections.addAll(list, files);
		}
		return list;
	}

	/**
	 * 获取目录下所有文件包括子目录
	 *
	 * @param dirPath 目录路径
	 * @return 文件链表
	 */
	public static List<File> listFilesInDir(final String dirPath) {
		return listFilesInDir(getFileByPath(dirPath));
	}

	/**
	 * 获取目录下所有文件包括子目录
	 *
	 * @param dir 目录
	 * @return 文件链表
	 */
	public static List<File> listFilesInDir(final File dir) {
		if (!isDir(dir)) return null;
		List<File> list = new ArrayList<>();
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				list.add(file);
				if (file.isDirectory()) {
					List<File> fileList = listFilesInDir(file);
					if (fileList != null) {
						list.addAll(fileList);
					}
				}
			}
		}
		return list;
	}

	/**
	 * 获取目录下所有后缀名为suffix的文件
	 * <p>大小写忽略</p>
	 *
	 * @param dirPath     目录路径
	 * @param suffix      后缀名
	 * @param isRecursive 是否递归进子目录
	 * @return 文件链表
	 */
	public static List<File> listFilesInDirWithFilter(final String dirPath, final String suffix, final boolean isRecursive) {
		return listFilesInDirWithFilter(getFileByPath(dirPath), suffix, isRecursive);
	}

	/**
	 * 获取目录下所有后缀名为suffix的文件
	 * <p>大小写忽略</p>
	 *
	 * @param dir         目录
	 * @param suffix      后缀名
	 * @param isRecursive 是否递归进子目录
	 * @return 文件链表
	 */
	public static List<File> listFilesInDirWithFilter(final File dir, final String suffix, final boolean isRecursive) {
		if (isRecursive) return listFilesInDirWithFilter(dir, suffix);
		if (dir == null || !isDir(dir)) return null;
		List<File> list = new ArrayList<>();
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				if (file.length() > 10) {
					if (file.getName().toUpperCase().endsWith(suffix.toUpperCase())) {
						list.add(file);
					}
				}
			}
		}
		return list;
	}

	/**
	 * 获取目录下所有后缀名为suffix的文件包括子目录
	 * <p>大小写忽略</p>
	 *
	 * @param dirPath 目录路径
	 * @param suffix  后缀名
	 * @return 文件链表
	 */
	public static List<File> listFilesInDirWithFilter(final String dirPath, final String suffix) {
		return listFilesInDirWithFilter(getFileByPath(dirPath), suffix);
	}

	/**
	 * 获取目录下所有后缀名为suffix的文件包括子目录
	 * <p>大小写忽略</p>
	 *
	 * @param dir    目录
	 * @param suffix 后缀名
	 * @return 文件链表
	 */
	public static List<File> listFilesInDirWithFilter(final File dir, final String suffix) {
		if (dir == null || !isDir(dir)) return null;
		List<File> list = new ArrayList<>();
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				if (file.getName().toUpperCase().endsWith(suffix.toUpperCase())) {
					list.add(file);
				}
				if (file.isDirectory()) {
					list.addAll(listFilesInDirWithFilter(file, suffix));
				}
			}
		}
		return list;
	}

	/**
	 * 获取目录下所有符合filter的文件
	 *
	 * @param dirPath     目录路径
	 * @param filter      过滤器
	 * @param isRecursive 是否递归进子目录
	 * @return 文件链表
	 */
	public static List<File> listFilesInDirWithFilter(final String dirPath, final FilenameFilter filter, final boolean isRecursive) {
		return listFilesInDirWithFilter(getFileByPath(dirPath), filter, isRecursive);
	}

	/**
	 * 获取目录下所有符合filter的文件
	 *
	 * @param dir         目录
	 * @param filter      过滤器
	 * @param isRecursive 是否递归进子目录
	 * @return 文件链表
	 */
	public static List<File> listFilesInDirWithFilter(final File dir, final FilenameFilter filter, final boolean isRecursive) {
		if (isRecursive) return listFilesInDirWithFilter(dir, filter);
		if (dir == null || !isDir(dir)) return null;
		List<File> list = new ArrayList<>();
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				if (filter.accept(file.getParentFile(), file.getName())) {
					list.add(file);
				}
			}
		}
		return list;
	}

	/**
	 * 获取目录下所有符合filter的文件包括子目录
	 *
	 * @param dirPath 目录路径
	 * @param filter  过滤器
	 * @return 文件链表
	 */
	public static List<File> listFilesInDirWithFilter(final String dirPath, final FilenameFilter filter) {
		return listFilesInDirWithFilter(getFileByPath(dirPath), filter);
	}

	/**
	 * 获取目录下所有符合filter的文件包括子目录
	 *
	 * @param dir    目录
	 * @param filter 过滤器
	 * @return 文件链表
	 */
	public static List<File> listFilesInDirWithFilter(final File dir, final FilenameFilter filter) {
		if (dir == null || !isDir(dir)) return null;
		List<File> list = new ArrayList<>();
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				if (filter.accept(file.getParentFile(), file.getName())) {
					list.add(file);
				}
				if (file.isDirectory()) {
					list.addAll(listFilesInDirWithFilter(file, filter));
				}
			}
		}
		return list;
	}

	/**
	 * 获取目录下指定文件名的文件包括子目录
	 * <p>大小写忽略</p>
	 *
	 * @param dirPath  目录路径
	 * @param fileName 文件名
	 * @return 文件链表
	 */
	public static List<File> searchFileInDir(final String dirPath, final String fileName) {
		return searchFileInDir(getFileByPath(dirPath), fileName);
	}

	/**
	 * 获取目录下指定文件名的文件包括子目录
	 * <p>大小写忽略</p>
	 *
	 * @param dir      目录
	 * @param fileName 文件名
	 * @return 文件链表
	 */
	public static List<File> searchFileInDir(final File dir, final String fileName) {
		if (dir == null || !isDir(dir)) return null;
		List<File> list = new ArrayList<>();
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				if (file.getName().toUpperCase().equals(fileName.toUpperCase())) {
					list.add(file);
				}
				if (file.isDirectory()) {
					list.addAll(searchFileInDir(file, fileName));
				}
			}
		}
		return list;
	}

	/**
	 * 获取文件最后修改的毫秒时间戳
	 *
	 * @param filePath 文件路径
	 * @return 文件最后修改的毫秒时间戳
	 */
	public static long getFileLastModified(final String filePath) {
		return getFileLastModified(getFileByPath(filePath));
	}

	/**
	 * 获取文件最后修改的毫秒时间戳
	 *
	 * @param file 文件
	 * @return 文件最后修改的毫秒时间戳
	 */
	public static long getFileLastModified(final File file) {
		if (file == null) return -1;
		return file.lastModified();
	}

	/**
	 * 简单获取文件编码格式
	 *
	 * @param filePath 文件路径
	 * @return 文件编码
	 */
	public static String getFileCharsetSimple(final String filePath) {
		return getFileCharsetSimple(getFileByPath(filePath));
	}

	/**
	 * 简单获取文件编码格式
	 *
	 * @param file 文件
	 * @return 文件编码
	 */
	public static String getFileCharsetSimple(final File file) {
		int p = 0;
		InputStream is = null;
		try {
			is = new BufferedInputStream(new FileInputStream(file));
			p = (is.read() << 8) + is.read();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			closeIO(is);
		}
		switch (p) {
			case 0xefbb:
				return "UTF-8";
			case 0xfffe:
				return "Unicode";
			case 0xfeff:
				return "UTF-16BE";
			default:
				return "GBK";
		}
	}

	/**
	 * 获取文件行数
	 *
	 * @param filePath 文件路径
	 * @return 文件行数
	 */
	public static int getFileLines(final String filePath) {
		return getFileLines(getFileByPath(filePath));
	}

	/**
	 * 获取文件行数
	 * <p>比readLine要快很多</p>
	 *
	 * @param file 文件
	 * @return 文件行数
	 */
	public static int getFileLines(final File file) {
		int count = 1;
		InputStream is = null;
		try {
			is = new BufferedInputStream(new FileInputStream(file));
			byte[] buffer = new byte[1024];
			int readChars;
			if (LINE_SEP.endsWith("\n")) {
				while ((readChars = is.read(buffer, 0, 1024)) != -1) {
					for (int i = 0; i < readChars; ++i) {
						if (buffer[i] == '\n') ++count;
					}
				}
			} else {
				while ((readChars = is.read(buffer, 0, 1024)) != -1) {
					for (int i = 0; i < readChars; ++i) {
						if (buffer[i] == '\r') ++count;
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			closeIO(is);
		}
		return count;
	}

	private static void closeIO(InputStream is) {
		if (is != null) {
			try {
				is.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * 获取目录大小
	 *
	 * @param dirPath 目录路径
	 * @return 文件大小
	 */
	public static String getDirSize(final String dirPath) {
		return getDirSize(getFileByPath(dirPath));
	}

	/**
	 * 获取目录大小
	 *
	 * @param dir 目录
	 * @return 文件大小
	 */
	public static String getDirSize(final File dir) {
		long len = getDirLength(dir);
		return len == -1 ? "" : byte2FitMemorySize(len);
	}

//    /**
//     * 获取文件大小
//     *
//     * @param filePath 文件路径
//     * @return 文件大小
//     */
//    public static String getFileSize(final String filePath) {
//        return getFileSize(getFileByPath(filePath));
//    }
//
//    /**
//     * 获取文件大小
//     *
//     * @param file 文件
//     * @return 文件大小
//     */
//    public static String getFileSize(final File file) {
//        long len = getFileLength(file);
//        return len == -1 ? "" : byte2FitMemorySize(len);
//    }

	/**
	 * 获取目录长度
	 *
	 * @param dirPath 目录路径
	 * @return 目录长度
	 */
	public static long getDirLength(final String dirPath) {
		return getDirLength(getFileByPath(dirPath));
	}

	/**
	 * 获取目录长度
	 *
	 * @param dir 目录
	 * @return 目录长度
	 */
	public static long getDirLength(final File dir) {
		if (!isDir(dir)) return -1;
		long len = 0;
		File[] files = dir.listFiles();
		if (files != null && files.length != 0) {
			for (File file : files) {
				if (file.isDirectory()) {
					len += getDirLength(file);
				} else {
					len += file.length();
				}
			}
		}
		return len;
	}

	/**
	 * 获取文件长度
	 *
	 * @param filePath 文件路径
	 * @return 文件长度
	 */
	public static long getFileLength(final String filePath) {
		return getFileLength(getFileByPath(filePath));
	}

	/**
	 * 获取文件长度
	 *
	 * @param file 文件
	 * @return 文件长度
	 */
	public static long getFileLength(final File file) {
		if (!isFile(file)) return -1;
		return file.length();
	}

	/**
	 * 获取文件的MD5校验码
	 *
	 * @param filePath 文件路径
	 * @return 文件的MD5校验码
	 */
	public static String getFileMD5ToString(final String filePath) {
		File file = isSpace(filePath) ? null : new File(filePath);
		return getFileMD5ToString(file);
	}

	/**
	 * 获取文件的MD5校验码
	 *
	 * @param filePath 文件路径
	 * @return 文件的MD5校验码
	 */
	public static byte[] getFileMD5(final String filePath) {
		File file = isSpace(filePath) ? null : new File(filePath);
		return getFileMD5(file);
	}

	/**
	 * 获取文件的MD5校验码
	 *
	 * @param file 文件
	 * @return 文件的MD5校验码
	 */
	public static String getFileMD5ToString(final File file) {
		return bytes2HexString(getFileMD5(file));
	}

	/**
	 * 获取文件的MD5校验码
	 *
	 * @param file 文件
	 * @return 文件的MD5校验码
	 */
	public static byte[] getFileMD5(final File file) {
		if (file == null) return null;
		DigestInputStream dis = null;
		try {
			FileInputStream fis = new FileInputStream(file);
			MessageDigest md = MessageDigest.getInstance("MD5");
			dis = new DigestInputStream(fis, md);
			byte[] buffer = new byte[1024 * 256];
			while (true) {
				if (!(dis.read(buffer) > 0)) break;
			}
			md = dis.getMessageDigest();
			return md.digest();
		} catch (NoSuchAlgorithmException | IOException e) {
			e.printStackTrace();
		} finally {
			closeIO(dis);
		}
		return null;
	}

	/**
	 * 获取全路径中的最长目录
	 *
	 * @param file 文件
	 * @return filePath最长目录
	 */
	public static String getDirName(final File file) {
		if (file == null) return null;
		return getDirName(file.getPath());
	}

	/**
	 * 获取全路径中的最长目录
	 *
	 * @param filePath 文件路径
	 * @return filePath最长目录
	 */
	public static String getDirName(final String filePath) {
		if (isSpace(filePath)) return filePath;
		int lastSep = filePath.lastIndexOf(File.separator);
		return lastSep == -1 ? "" : filePath.substring(0, lastSep + 1);
	}

	/**
	 * 获取全路径中的文件名
	 *
	 * @param filePath 文件路径
	 * @return 文件名
	 */
	public static String getFileName(final String filePath) {
		if (isSpace(filePath)) return filePath;
		int lastSep = filePath.lastIndexOf(File.separator);
		return lastSep == -1 ? filePath : filePath.substring(lastSep + 1);
	}

	/**
	 * 获取全路径中的不带拓展名的文件名
	 *
	 * @param file 文件
	 * @return 不带拓展名的文件名
	 */
	public static String getFileNameNoExtension(final File file) {
		if (file == null) return null;
		return getFileNameNoExtension(file.getPath());
	}

	/**
	 * 获取全路径中的不带拓展名的文件名
	 *
	 * @param filePath 文件路径
	 * @return 不带拓展名的文件名
	 */
	public static String getFileNameNoExtension(final String filePath) {
		if (isSpace(filePath)) return filePath;
		int lastPoi = filePath.lastIndexOf('.');
		int lastSep = filePath.lastIndexOf(File.separator);
		if (lastSep == -1) {
			return (lastPoi == -1 ? filePath : filePath.substring(0, lastPoi));
		}
		if (lastPoi == -1 || lastSep > lastPoi) {
			return filePath.substring(lastSep + 1);
		}
		return filePath.substring(lastSep + 1, lastPoi);
	}

	/**
	 * 获取全路径中的文件拓展名
	 *
	 * @param file 文件
	 * @return 文件拓展名
	 */
	public static String getFileExtension(final File file) {
		if (file == null) return null;
		return getFileExtension(file.getPath());
	}

	/**
	 * 获取全路径中的文件拓展名
	 *
	 * @param filePath 文件路径
	 * @return 文件拓展名
	 */
	public static String getFileExtension(final String filePath) {
		if (isSpace(filePath)) return filePath;
		int lastPoi = filePath.lastIndexOf('.');
		int lastSep = filePath.lastIndexOf(File.separator);
		if (lastPoi == -1 || lastSep >= lastPoi) return "";
		return filePath.substring(lastPoi + 1);
	}

	/**
	 * 根据文件类型去删除其在系统中对应的Media数据库
	 *
	 * @param file
	 * @return -1代表不是媒体文件，0表示在数据库中查找不到，1找到数据库中对应的数据，并且删除
	 */
	public static int deleteMedia(File file) {
		String name = file.getName();
		String path = file.getAbsolutePath();
		if (name.contains(".jpg") || name.contains(".mp4")) {
			Uri MEDIA_URI = null;
			if (name.contains(".jpg")) {
				if (path.contains("mnt/sdcard/")) {
					MEDIA_URI = MediaStore.Images.Media.INTERNAL_CONTENT_URI;
					path = path.replace("/mnt/sdcard/", "/storage/sdcard0/");
				} else if (file.getAbsolutePath().contains("mnt/sdcard2/")) {
					MEDIA_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
					path = path.replace("/mnt/sdcard2/", "/storage/sdcard1/");
				}
			} else {
				if (path.contains("mnt/sdcard/")) {
					MEDIA_URI = MediaStore.Video.Media.INTERNAL_CONTENT_URI;
					path = path.replace("/mnt/sdcard1/", "/storage/sdcard0/");
				} else if (file.getAbsolutePath().contains("mnt/sdcard2/")) {
					MEDIA_URI = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
					path = path.replace("/mnt/sdcard2/", "/storage/sdcard1/");
				}
			}
			int resultCode = 0;
			// resultCode = MyApp.getInstance().getContentResolver().delete(MEDIA_URI, MediaStore.Images.Media.DATA+"="+"'"+path+"'" , null);
			return resultCode;
		} else {
			return -1;
		}
	}
	///
	// copy from ConvertUtils
	///

	private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

	/**
	 * byteArr转hexString
	 * <p>例如：</p>
	 * bytes2HexString(new byte[] { 0, (byte) 0xa8 }) returns 00A8
	 *
	 * @param bytes 字节数组
	 * @return 16进制大写字符串
	 */
	private static String bytes2HexString(final byte[] bytes) {
		if (bytes == null) return null;
		int len = bytes.length;
		if (len <= 0) return null;
		char[] ret = new char[len << 1];
		for (int i = 0, j = 0; i < len; i++) {
			ret[j++] = hexDigits[bytes[i] >>> 4 & 0x0f];
			ret[j++] = hexDigits[bytes[i] & 0x0f];
		}
		return new String(ret);
	}

	/**
	 * 字节数转合适内存大小
	 * <p>保留3位小数</p>
	 *
	 * @param byteNum 字节数
	 * @return 合适内存大小
	 */
	@SuppressLint("DefaultLocale")
	private static String byte2FitMemorySize(final long byteNum) {
		if (byteNum < 0) {
			return "shouldn't be less than zero!";
		} else if (byteNum < 1024) {
			return String.format("%.3fB", (double) byteNum + 0.0005);
		} else if (byteNum < 1048576) {
			return String.format("%.3fKB", (double) byteNum / 1024 + 0.0005);
		} else if (byteNum < 1073741824) {
			return String.format("%.3fMB", (double) byteNum / 1048576 + 0.0005);
		} else {
			return String.format("%.3fGB", (double) byteNum / 1073741824 + 0.0005);
		}
	}

	private static boolean isSpace(final String s) {
		if (s == null) return true;
		for (int i = 0, len = s.length(); i < len; ++i) {
			if (!Character.isWhitespace(s.charAt(i))) {
				return false;
			}
		}
		return true;
	}

	// ---------------

	/**
	 * 在指定的位置创建指定的文件
	 *
	 * @param filePath 完整的文件路径
	 * @param mkdir    是否创建相关的文件夹
	 * @throws IOException
	 */
	public static void mkFile(String filePath, boolean mkdir) throws IOException {
		File file = new File(filePath);
		/**
		 * mkdirs()创建多层目录，mkdir()创建单层目录
		 * writeObject时才创建磁盘文件。
		 * 若不创建文件，readObject出错。
		 */
		file.getParentFile().mkdirs();
		file.createNewFile();
		file = null;
	}

	/**
	 * 在指定的位置创建文件夹
	 *
	 * @param dirPath 文件夹路径
	 * @return 若创建成功，则返回True；反之，则返回False
	 */
	public static boolean mkDir(String dirPath) {
		return new File(dirPath).mkdirs();
	}

	/**
	 * 删除指定的文件
	 *
	 * @param filePath 文件路径
	 * @return 若删除成功，则返回True；反之，则返回False
	 */
	public static boolean delFile(String filePath) {
		return new File(filePath).delete();
	}

	/**
	 * 删除指定的文件夹
	 *
	 * @param dirPath 文件夹路径
	 * @param delFile 文件夹中是否包含文件
	 * @return 若删除成功，则返回True；反之，则返回False
	 */
	public static boolean delDir(String dirPath, boolean delFile) {
		if (delFile) {
			File file = new File(dirPath);
			if (file.isFile()) {
				return file.delete();
			} else if (file.isDirectory()) {
				if (file.listFiles().length == 0) {
					return file.delete();
				} else {
					int zFiles = file.listFiles().length;
					File[] delfile = file.listFiles();
					for (int i = 0; i < zFiles; i++) {
						if (delfile[i].isDirectory()) {
							delDir(delfile[i].getAbsolutePath(), true);
						}
						delfile[i].delete();
					}
					return file.delete();
				}
			} else {
				return false;
			}
		} else {
			return new File(dirPath).delete();
		}
	}

	/**
	 * 复制文件/文件夹 若要进行文件夹复制，请勿将目标文件夹置于源文件夹中
	 *
	 * @param source   源文件（夹）
	 * @param target   目标文件（夹）
	 * @param isFolder 若进行文件夹复制，则为True；反之为False
	 * @throws IOException
	 */
	public static void copy(String source, String target, boolean isFolder) throws IOException {
		if (isFolder) {
			new File(target).mkdirs();
			File a = new File(source);
			String[] file = a.list();
			File temp = null;
			for (int i = 0; i < file.length; i++) {
				if (source.endsWith(File.separator)) {
					temp = new File(source + file[i]);
				} else {
					temp = new File(source + File.separator + file[i]);
				}
				if (temp.isFile()) {
					FileInputStream input = new FileInputStream(temp);
					FileOutputStream output = new FileOutputStream(target + File.separator + temp.getName().toString());
					byte[] b = new byte[1024];
					int len;
					while ((len = input.read(b)) != -1) {
						output.write(b, 0, len);
					}
					output.flush();
					output.close();
					input.close();
				}
				if (temp.isDirectory()) {
					copy(source + File.separator + file[i], target + File.separator + file[i], true);
				}
			}
		} else {
			int byteread = 0;
			File oldfile = new File(source);
			if (oldfile.exists()) {
				InputStream inputStream = new FileInputStream(source);
				File file = new File(target);
				file.getParentFile().mkdirs();
				file.createNewFile();
				FileOutputStream outputStream = new FileOutputStream(file);
				byte[] buffer = new byte[1024];
				while ((byteread = inputStream.read(buffer)) != -1) {
					outputStream.write(buffer, 0, byteread);
				}
				inputStream.close();
				outputStream.close();
			}
		}
	}

	/**
	 * @param context
	 * @param ext     后缀 .jpg
	 * @param type    Environment.DIRECTORY_MUSIC
	 *                Environment.DIRECTORY_PICTURE
	 * @return
	 * @throws IOException
	 */
	public static File getTempFilePath(Context context, String type, String ext) {
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
		//进行图片名称进行拼接
		String fileName = "temp_" + timeStamp;

		//获得该应用包下文件的Pictures目录（如果没有会自动创建）
		File storageDir = context.getExternalFilesDir(type);
		//创建image文件
		return new File(storageDir, fileName + ext);
	}

	/**
	 * 根据Uri获取文件的绝对路径，解决Android4.4以上版本Uri转换
	 *
	 * @param context
	 * @param fileUri
	 */
	@TargetApi(19)
	public static String getFileAbsolutePath(Activity context, Uri fileUri) {
		if (context == null || fileUri == null)
			return null;
		if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, fileUri)) {
			if (isExternalStorageDocument(fileUri)) {
				String docId = DocumentsContract.getDocumentId(fileUri);
				String[] split = docId.split(":");
				String type = split[0];
				if ("primary".equalsIgnoreCase(type)) {
					return Environment.getExternalStorageDirectory() + "/" + split[1];
				}
			} else if (isDownloadsDocument(fileUri)) {
				String id = DocumentsContract.getDocumentId(fileUri);
				Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
				return getDataColumn(context, contentUri, null, null);
			} else if (isMediaDocument(fileUri)) {
				String docId = DocumentsContract.getDocumentId(fileUri);
				String[] split = docId.split(":");
				String type = split[0];
				Uri contentUri = null;
				if ("image".equals(type)) {
					contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
				} else if ("video".equals(type)) {
					contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
				} else if ("audio".equals(type)) {
					contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
				}
				String selection = MediaStore.Images.Media._ID + "=?";
				String[] selectionArgs = new String[]{split[1]};
				return getDataColumn(context, contentUri, selection, selectionArgs);
			}
		} // MediaStore (and general)
		else if ("content".equalsIgnoreCase(fileUri.getScheme())) {
			// Return the remote address
			if (isGooglePhotosUri(fileUri))
				return fileUri.getLastPathSegment();
			return getDataColumn(context, fileUri, null, null);
		}
		// File
		else if ("file".equalsIgnoreCase(fileUri.getScheme())) {
			return fileUri.getPath();
		}
		return null;
	}

	public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
		Cursor cursor = null;
		String[] projection = {MediaStore.Images.Media.DATA};
		try {
			cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
			if (cursor != null && cursor.moveToFirst()) {
				int index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
				return cursor.getString(index);
			}
		} finally {
			if (cursor != null)
				cursor.close();
		}
		return null;
	}

	/**
	 * @param uri The Uri to check.
	 * @return Whether the Uri authority is ExternalStorageProvider.
	 */
	public static boolean isExternalStorageDocument(Uri uri) {
		return "com.android.externalstorage.documents".equals(uri.getAuthority());
	}

	/**
	 * @param uri The Uri to check.
	 * @return Whether the Uri authority is DownloadsProvider.
	 */
	public static boolean isDownloadsDocument(Uri uri) {
		return "com.android.providers.downloads.documents".equals(uri.getAuthority());
	}

	/**
	 * @param uri The Uri to check.
	 * @return Whether the Uri authority is MediaProvider.
	 */
	public static boolean isMediaDocument(Uri uri) {
		return "com.android.providers.media.documents".equals(uri.getAuthority());
	}

	/**
	 * @param uri The Uri to check.
	 * @return Whether the Uri authority is Google Photos.
	 */
	public static boolean isGooglePhotosUri(Uri uri) {
		return "com.google.android.apps.photos.content".equals(uri.getAuthority());
	}


	public static String getExtensionName(String filePath) throws Exception {
		File file = new File(filePath);
		return getExtensionName(file);
	}

	public static String getExtensionName(File file) {
		String fileName = file.getName();
		return fileName.substring(fileName.lastIndexOf(".") + 1);
	}

	/**
	 * 获取文件指定文件的指定单位的大小
	 *
	 * @param filePath 文件路径
	 * @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB
	 * @return double值的大小
	 */
	public static double getFileSize(String filePath, int sizeType) {
		File file = new File(filePath);
		long blockSize = 0;
		try {
			if (file.isDirectory()) {
				blockSize = getFileSizes(file);
			} else {
				blockSize = getFileSize(file);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return formatFileSize(blockSize, sizeType);
	}

	/**
	 * 获取指定文件大小
	 * 1、file.length()方法，类型long Byte。支持大文件（9223372036854775807），文件大小不准。
	 * 2、fileInputStream.available()方法，类型int，最大(1.99GB)，大文件返回0。文件大小准确
	 * 3、java.nio.*下的FileChannel，支持大文件，文件大小准确。
	 *
	 * @param file
	 * @return
	 * @throws Exception
	 */
	private static long getFileSize(File file) throws Exception {
		long size = 0;
		if (file.exists() && file.isFile()) {
			FileInputStream fis = null;
			try {
				fis = new FileInputStream(file);
				size = fis.available();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (null != fis) {
					try {
						fis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
		return size;
	}

	/**
	 * 获取指定文件夹
	 *
	 * @param f
	 * @return
	 * @throws Exception
	 */
	private static long getFileSizes(File f) throws Exception {
		long size = 0;
		File flist[] = f.listFiles();
		for (int i = 0; i < flist.length; i++) {
			if (flist[i].isDirectory()) {
				size = size + getFileSizes(flist[i]);
			} else {
				size = size + getFileSize(flist[i]);
			}
		}
		return size;
	}

	/**
	 * 转换文件大小
	 *
	 * @param fileS
	 * @return
	 */
	private static String formatFileSize(long fileS) {
		DecimalFormat df = new DecimalFormat("#.00");
		String fileSizeString = "";
		String wrongSize = "0B";
		if (fileS == 0) {
			return wrongSize;
		}
		if (fileS < 1024) {
			fileSizeString = df.format((double) fileS) + "B";
		} else if (fileS < 1048576) {
			fileSizeString = df.format((double) fileS / 1024) + "KB";
		} else if (fileS < 1073741824) {
			fileSizeString = df.format((double) fileS / 1048576) + "MB";
		} else {
			fileSizeString = df.format((double) fileS / 1073741824) + "GB";
		}
		return fileSizeString;
	}

	/**
	 * 转换文件大小,指定转换的类型
	 *
	 * @param fileS
	 * @param sizeType
	 * @return
	 */
	private static double formatFileSize(long fileS, int sizeType) {
		DecimalFormat df = new DecimalFormat("#.00");
		double fileSizeLong = 0;
		switch (sizeType) {
			case SIZETYPE_B:
				fileSizeLong = Double.valueOf(df.format((double) fileS));
				break;
			case SIZETYPE_KB:
				fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
				break;
			case SIZETYPE_MB:
				fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
				break;
			case SIZETYPE_GB:
				fileSizeLong = Double.valueOf(df.format((double) fileS / 1073741824));
				break;
			default:
				break;
		}
		return fileSizeLong;
	}
}
